import Vue from "vue";
import VueRouter from "vue-router";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { defaultRoutes } from "./default/index";
import globalSite from "@/config/globalSite";
import { isLogin, getAuthToken, getAccessToken } from "@/util/auth";
import store from "@/store";
import { loginDisable } from "@/util/common";

Vue.use(VueRouter);

const routes = defaultRoutes;

const router = new VueRouter({
  mode: "history",
  base: "/",
  // 切换路由后，页面返回顶部
  scrollBehavior: (to, from, savedPosition) => {
    // savedPosition 这个参数当且仅当导航 (通过浏览器的 前进/后退 按钮触发) 时才可用  效果和 router.go() 或 router.back()
    if (savedPosition) {
      // 返回savedPosition 其实就是 当用户点击 返回的话，保持之前游览的高度
      return savedPosition;
    } else {
      if (from.meta.keepAlive) {
        const formData = from;
        formData.meta.savedPosition = document.body.scrollTop;
      }
      return {
        x: 0,
        y: to.meta.savedPosition || 0
      };
    }
  },
  routes
});

router.beforeEach((to, from, next) => {
  // console.log("beforeEach", to.name)
  // 开启 progress
  NProgress.start();
  // 判断是否存在token
  if (isLogin()) {
    // 需要退登才能跳转到登录注册
    if (to.name === "login" || to.name === "register") {
      next("/");
    } else {
      // 这里的判断用于避免每次路由切换时发起静默登录
      if (!store.state.user.isLogin) {
        let accessToken = getAccessToken();
        let authToken = getAuthToken();
        store
          .dispatch("silentLogin", {
            accessToken: accessToken,
            authToken: authToken,
            terminalFlag: 4
          })
          .then(() => {
            next({
              ...to,
              replace: true
            }); // hack方法 确保addRoutes已完成
          });
      } else {
        next();
      }
    }
  } else {
    // 访问的页面是否在白名单内，白名单的页面可直接访问
    if (globalSite.whiteList.indexOf(to.name) !== -1) {
      next();
    } else {
      if (loginDisable()) {
        // 禁止登录状态下，不能跳转到登录页
        next("/");
      } else {
        next("/login");
      }
    }
  }
  next();
});

router.afterEach(() => {
  // 关闭 progress
  NProgress.done();
});

// 重复路由控制台报错的解决方案
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location, onResolve, onReject) {
  if (onResolve || onReject)
    return originalPush.call(this, location, onResolve, onReject);
  return originalPush.call(this, location).catch(err => err);
};

// 重置路由
export function resetRouter() {
  // console.log("resetRouter");
  router.matcher = new VueRouter({
    routes: defaultRoutes
  }).matcher;
}

export default router;
